const getStyle = (el, attr) => {
  return getComputedStyle(el)[attr]
}

const getStyles = (el, styles) => {
  const result = {}
  for (const key of styles) {
    result[key] = getStyle(el, key)
  }
  return result
}

const setStyle = (el, name, value) => {
  el['style'][name] = value
}

const setStyles = (el, styles) => {
  for (let key in styles) {
    setStyle(el, key, styles[key])
  }
}

const drag = function (el, binding) {
  let moveEl = el
  let x, y

  const styles = getStyles(el, ['position'])
  if (binding.value) {
    const { target } = binding.value
    if (target) {
      moveEl = el.querySelector(target) || moveEl
    }
  }
  setStyles(el, { position: 'absolute', 'z-index': 999, transform: 'none' })
  setStyles(moveEl, {
    cursor: 'move',
    'user-select': 'none',
  })

  const handleMouseDown = (e) => {
    x = e.clientX - el.offsetLeft
    y = e.clientY - el.offsetTop
    if (e.button === 0) {
      window.addEventListener('mousemove', handleMouseMove)
      window.addEventListener('mouseup', handleMouseUp)
    }
  }

  const handleMouseMove = (e) => {
    let moveX = e.clientX - x
    let moveY = e.clientY - y
    const moveWidth = document.documentElement.offsetWidth - el.offsetWidth
    const moveHeight = document.documentElement.offsetHeight - el.offsetHeight
    if (moveX <= 0) {
      moveX = 0
    }
    if (moveX >= moveWidth) {
      moveX = moveWidth
    }
    if (moveY <= 0) {
      moveY = 0
    }
    if (moveY >= moveHeight) {
      moveY = moveHeight
    }
    el.style.left = `${moveX}px`
    el.style.top = `${moveY}px`
  }

  const handleMouseUp = () => {
    window.removeEventListener('mousemove', handleMouseMove)
    window.removeEventListener('mouseup', handleMouseUp)

    setStyles(el, styles)
  }

  moveEl.addEventListener('mousedown', handleMouseDown)
}

export default drag
